package com.distribute.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.session.ExpiringSession;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import com.distribute.captcha.ValidateCodeFilter;
import com.distribute.common.Constant;


@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private AuthenticationSuccessHandler authenticationSuccessHandler;
	@Autowired
	private AuthenticationFailureHandler authenticationFailureHandler;
	@Autowired
	private LogoutSuccessHandler logoutSuccessHandler;
	@Autowired
	private AuthenticationEntryPoint authenticationEntryPoint;
	@Autowired
	private ValidateCodeFilter	validateCodeFilter;
	@Autowired
    private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
	
	@Bean
	public BCryptPasswordEncoder bCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	@Bean
    SpringSessionBackedSessionRegistry sessionRegistry() {
        return new SpringSessionBackedSessionRegistry((FindByIndexNameSessionRepository<ExpiringSession>) this.sessionRepository);
    }
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable();
		
		http.sessionManagement().maximumSessions(1)
			.maxSessionsPreventsLogin(true)
			.sessionRegistry(sessionRegistry());
		http.authorizeRequests()
				.antMatchers(Constant.DEFAULT_WHITE_URLS).permitAll()
				.anyRequest().authenticated();
		http.formLogin().loginPage(Constant.LOGIN_PAGE_URL).loginProcessingUrl(Constant.DO_LOGIN_URL)
				.successHandler(authenticationSuccessHandler)
				.failureHandler(authenticationFailureHandler)
				.and()
				.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
		http.logout().logoutUrl(Constant.DO_LOGOUT_URL)
			.logoutSuccessHandler(logoutSuccessHandler).deleteCookies(Constant.COOKIE_NAME);
		
		// 解决不允许显示在iframe的问题
		http.headers().frameOptions().disable();
		http.headers().cacheControl();
		
		//用户名密码之前添加校验码过滤器
		http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
	}
}
